/**
 *
 * @author poemdexter and updated to work with listener by Eric Hushagen
 */

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;

public class poemFishingListener extends PluginListener {

    protected static final Logger log = Logger.getLogger("Minecraft");
    private List<String> isFishing = new LinkedList();
    private Random generator = new Random();

    public boolean onCommand(Player player, String[] split) {
        if (!player.canUseCommand(split[0])) {
            return false;
        }

        if (split[0].equalsIgnoreCase("/bucket")) {

            if (split.length == 1) {
                doBucketList(player);
                return true;
            }

            if (split.length != 3) {
                player.sendMessage(Colors.Rose + "Correct usage is: /bucket [itemID] [amount]");
                return true;
            }

            int itemNum = -1;
            try {
                itemNum = Integer.parseInt(split[1]);
            } catch (NumberFormatException ex) {
                player.sendMessage(Colors.Rose + split[1] + " is not valid for itemID.");
                return true;
            }

            int amtNum = -1;
            try {
                amtNum = Integer.parseInt(split[2]);
            } catch (NumberFormatException ex) {
                player.sendMessage(Colors.Rose + split[2] + " is not valid for amount.");
                return true;
            }

            if (amtNum < 1) {
                player.sendMessage(Colors.Rose + "Amount must be greater than 0.");
                return true;
            }

            int taken = -1;
            try {
                taken = takeFromBucket(player, itemNum, amtNum);
            } catch (NullPointerException np) {
                player.sendMessage(Colors.Rose + "Item Number must be valid.");
                return true;
            }
            if (taken == -1) {
                player.sendMessage(Colors.Rose + "You don't have that much " + itemNum);
                return true;
            }

            player.giveItem(itemNum, amtNum);
            player.sendMessage(itemNum + " left: " + taken);
            return true;

        } else {
            return false;
        }
    }

    public synchronized void doBucketList(Player player) {
        player.sendMessage(Colors.LightPurple + "ItemID | Item | Amount");
        for (Bucket bk : FishingMod.getInstance().getBucketList()) {
            if (bk.name.equals(player.getName())) {
                player.sendMessage(Colors.LightBlue + bk.itemNum + " | " + getItemName(bk.itemNum) + " | " + bk.itemAmt);
            }
        }
    }

    public boolean byWater(Player player) {

        double degreeRotation = ((player.getRotation() - 90) % 360);
        if (degreeRotation < 0) {
            degreeRotation += 360.0;
        }
        String facing = getDirection(degreeRotation);
        if (facing.equals("N")) {
            if (9 == etc.getInstance().getServer().getBlockIdAt(((int) player.getX()) - 1, ((int) player.getY()) - 1, (int) player.getZ())) {
                return true;
            }
        } else if (facing.equals("E")) {
            if (9 == etc.getInstance().getServer().getBlockIdAt((int) player.getX(), ((int) player.getY()) - 1, ((int) player.getZ()) - 1)) {
                return true;
            }
        } else if (facing.equals("S")) {
            if (9 == etc.getInstance().getServer().getBlockIdAt(((int) player.getX()) + 1, ((int) player.getY()) - 1, (int) player.getZ())) {
                return true;
            }
        } else if (facing.equals("W")) {
            if (9 == etc.getInstance().getServer().getBlockIdAt((int) player.getX(), ((int) player.getY()) - 1, ((int) player.getZ()) + 1)) {
                return true;
            }
        } else {
            player.sendMessage(Colors.Rose + "problem getting byWater(). tell poem.");
        }

        return false;
    }

    public static String getDirection(double degrees) {
        if (0 <= degrees && degrees < 45) {
            return "N";
        } else if (45 <= degrees && degrees < 135) {
            return "E";
        } else if (135 <= degrees && degrees < 225) {
            return "S";
        } else if (225 <= degrees && degrees < 315) {
            return "W";
        } else if (315 <= degrees && degrees < 360) {
            return "N";
        } else {
            return "";
        }
    }

    public synchronized void attemptCatch(Player player) {
        generator.setSeed(System.currentTimeMillis());
        int num1 = generator.nextInt(100) + 1;

        if (num1 > FishingMod.getInstance().getDataSource().getFishChance()) {

            int num2 = generator.nextInt(100) + 1;
            int currentTier = -1;
            for (Tier thisTier : FishingMod.getInstance().getDataSource().getTier()) {
                if (num2 >= thisTier.getMinroll() && num2 <= thisTier.getMaxroll()) {
                    currentTier = thisTier.getTier();
                }
            }

            int num3 = generator.nextInt(100) + 1;
            Fish currentFish = new Fish();
            for (Fish thisFish : FishingMod.getInstance().getDataSource().getFish()) {
                if (thisFish.getTier() == currentTier && num3 >= thisFish.getMinroll() && num3 <= thisFish.getMaxroll()) {
                    currentFish = thisFish;
                }
            }

            int num4 = generator.nextInt(20) + 1;
            if (num4 >= 1 && num4 <= 14) {
                addToBucket(player, currentFish.getItemNumber(), currentFish.getSmall());
                player.sendMessage(Colors.LightBlue + "You caught a " + currentFish.getName() + ".");
            } else if (num4 >= 15 && num4 <= 19) {
                addToBucket(player, currentFish.getItemNumber(), currentFish.getBig());
                player.sendMessage(Colors.LightBlue + "You caught a big " + currentFish.getName() + ".");
            } else {
                addToBucket(player, currentFish.getItemNumber(), currentFish.getHuge());
                String message = player.getName() + " has caught a HUGE " + currentFish.getName() + "!";
                tellAll(message);
                log.info("FISHING: " + message);
            }
        } else {
            player.sendMessage(Colors.LightBlue + "Not even a nibble.");
        }
    }

    public synchronized int takeFromBucket(Player player, int item, int amount) {

        Bucket takebucket = FishingMod.getInstance().getDataSource().getBucket(player.getName(), item);
        int takeAmt = takebucket.itemAmt;

        if (amount > takeAmt) {
            return -1;
        }

        Bucket newbk = new Bucket();
        newbk.name = player.getName();
        newbk.itemNum = item;
        newbk.itemAmt = takeAmt - amount;

        FishingMod.getInstance().getDataSource().removeBucket(takebucket);

        if (takeAmt - amount < 1) {
            FishingMod.getInstance().getBucketList().remove(takebucket);
        } else {
            FishingMod.getInstance().getDataSource().addBucket(newbk);
        }

        FishingMod.getInstance().load();
        FishingMod.getInstance().loadData();

        return takeAmt - amount;
    }

    public synchronized void addToBucket(Player player, int item, int amount) {

        Bucket oldbucket = FishingMod.getInstance().getDataSource().getBucket(player.getName(), item);

        if (oldbucket == null) {
            Bucket newbk = new Bucket();
            newbk.name = player.getName();
            newbk.itemNum = item;
            newbk.itemAmt = amount;

            FishingMod.getInstance().getDataSource().addBucket(newbk);
            FishingMod.getInstance().load();
            FishingMod.getInstance().loadData();
        } else {
            Bucket newbk = new Bucket();
            newbk.name = player.getName();
            newbk.itemNum = item;
            newbk.itemAmt = oldbucket.itemAmt + amount;

            FishingMod.getInstance().getDataSource().removeBucket(oldbucket);
            FishingMod.getInstance().getDataSource().addBucket(newbk);
            FishingMod.getInstance().load();
            FishingMod.getInstance().loadData();
        }
    }

    public void startFishingTimer(Player probPlayer) {
        final Timer timer = new Timer();
        final Player playr = probPlayer;
        timer.schedule(new TimerTask() {

            @Override
            public synchronized void run() {
                attemptCatch(playr);
                isFishing.remove(playr.getName());
                timer.cancel();
            }
        }, 5000);
    }

    public void tellAll(String message) {
        for (Player p : etc.getServer().getPlayerList()) {
            if (p != null) {
                p.sendMessage(Colors.LightBlue + message);
            }
        }
    }

    public boolean onBlockCreate(Player player, Block blockPlaced, Block blockClicked, int itemInHand) {

        if (itemInHand == 346) {
            if (!getIsFishing().contains(player.getName())) {
                if (byWater(player)) {
                    player.sendMessage(Colors.LightBlue + "BLOOP!");
                    getIsFishing().add(player.getName());
                    startFishingTimer(player);
                    return true;
                } else {
                    player.sendMessage(Colors.Rose + "You must be near water to fish.");
                    return false;
                }
            } else {
                player.sendMessage(Colors.Rose + "You must wait to fish again.");
                return false;
            }
        }
        return false;
    }

    public synchronized List<String> getIsFishing() {
        return isFishing;
    }

    public String getItemName(int i) {
        switch (i) {
            case 1:
                return "smooth stone";
            case 2:
                return "grass";
            case 3:
                return "dirt";
            case 4:
                return "cobblestone";
            case 5:
                return "wood planks";
            case 6:
                return "sapling";
            case 7:
                return "bedrock";
            case 8:
                return "water spring";
            case 9:
                return "water spring";
            case 10:
                return "lava spring";
            case 11:
                return "lava spring";
            case 12:
                return "sand";
            case 13:
                return "gravel";
            case 14:
                return "gold ore";
            case 15:
                return "iron ore";
            case 16:
                return "coal block";
            case 17:
                return "log";
            case 18:
                return "leaves";
            case 19:
                return "sponge";
            case 20:
                return "glass";
            case 35:
                return "wool";
            case 37:
                return "yellow flower";
            case 38:
                return "red flower";
            case 39:
                return "brown mushroom";
            case 40:
                return "red mushroom";
            case 41:
                return "gold block";
            case 42:
                return "iron block";
            case 43:
                return "double halfblock";
            case 44:
                return "half block";
            case 45:
                return "brick block";
            case 46:
                return "TNT";
            case 47:
                return "bookcase";
            case 48:
                return "mossy cobblestone";
            case 49:
                return "obsidian";
            case 50:
                return "torch";
            case 51:
                return "fire";
            case 52:
                return "spawner";
            case 53:
                return "wood stairs";
            case 54:
                return "chest";
            case 55:
                return "redstone powder";
            case 56:
                return "diamond ore";
            case 57:
                return "diamond block";
            case 58:
                return "crafting table";
            case 59:
                return "planted seeds";
            case 60:
                return "tilled dirt";
            case 61:
                return "furnace";
            case 62:
                return "furnace";
            case 65:
                return "ladder";
            case 66:
                return "rail";
            case 67:
                return "stone stairs";
            case 69:
                return "switch";
            case 70:
                return "stone plate";
            case 72:
                return "wooden plate";
            case 73:
                return "redstone ore";
            case 74:
                return "redstone ore";
            case 75:
                return "unlit redstone torch";
            case 76:
                return "redstone torch";
            case 77:
                return "button";
            case 78:
                return "snow covering";
            case 79:
                return "ice block";
            case 80:
                return "snow block";
            case 81:
                return "cactus";
            case 82:
                return "clay block";
            case 83:
                return "reeds";
            case 84:
                return "music box";
            case 85:
                return "fence";
            case 256:
                return "iron shovel";
            case 257:
                return "iron pickaxe";
            case 258:
                return "iron axe";
            case 259:
                return "lighter";
            case 260:
                return "apple";
            case 261:
                return "bow";
            case 262:
                return "arrow";
            case 263:
                return "coal";
            case 264:
                return "diamond";
            case 265:
                return "iron";
            case 266:
                return "gold";
            case 267:
                return "iron sword";
            case 268:
                return "wooden sword";
            case 269:
                return "wooden shovel";
            case 270:
                return "wooden pickaxe";
            case 271:
                return "wooden axe";
            case 272:
                return "stone sword";
            case 273:
                return "stone shovel";
            case 274:
                return "stone pickaxe";
            case 275:
                return "stone axe";
            case 276:
                return "diamond sword";
            case 277:
                return "diamond shovel";
            case 278:
                return "diamond pickaxe";
            case 279:
                return "diamond axe";
            case 280:
                return "stick";
            case 281:
                return "bowl";
            case 282:
                return "mushroom soup";
            case 283:
                return "gold sword";
            case 284:
                return "gold shovel";
            case 285:
                return "gold pickaxe";
            case 286:
                return "gold axe";
            case 287:
                return "string";
            case 288:
                return "feather";
            case 289:
                return "gunpowder";
            case 290:
                return "wooden hoe";
            case 291:
                return "stone hoe";
            case 292:
                return "iron hoe";
            case 293:
                return "diamond hoe";
            case 294:
                return "gold hoe";
            case 295:
                return "seeds";
            case 296:
                return "wheat";
            case 297:
                return "bread";
            case 298:
                return "leather helm";
            case 299:
                return "leather chest";
            case 300:
                return "leather pants";
            case 301:
                return "leather shoes";
            //ehushagen: add chainmail armour
            case 302:
                return "rusty helmet";
            case 303:
                return "rusty armour";
            case 304:
                return "rusty leggings";
            case 305:
                return "rusty boots";
            case 306:
                return "iron helm";
            case 307:
                return "iron chest";
            case 308:
                return "iron pants";
            case 309:
                return "iron shoes";
            case 310:
                return "diamond helm";
            case 311:
                return "diamond chest";
            case 312:
                return "diamond pants";
            case 313:
                return "diamond shoes";
            case 314:
                return "gold helm";
            case 315:
                return "gold chest";
            case 316:
                return "gold pants";
            case 317:
                return "gold shoes";
            case 318:
                return "flint";
            case 319:
                return "uncooked meat";
            case 320:
                return "cooked meat";
            case 321:
                return "painting";
            case 322:
                return "golden apple";
            case 323:
                return "sign";
            case 324:
                return "wooden door";
            case 325:
                return "bucket";
            case 326:
                return "water bucket";
            case 327:
                return "lava bucket";
            case 328:
                return "minecart";
            case 329:
                return "saddle";
            case 330:
                return "iron door";
            case 331:
                return "redstone powder";
            case 332:
                return "snowball";
            case 333:
                return "boat";
            case 334:
                return "leather";
            case 335:
                return "milk bucket";
            case 336:
                return "clay block";
            case 337:
                return "clay ball";
            case 338:
                return "reeds";
            case 339:
                return "paper";
            case 340:
                return "book";
            case 341:
                return "slimeball";
            case 342:
                return "chestcart";
            case 343:
                return "funacecart";
            case 344:
                return "egg";
            case 345:
                return "compass";
            case 2256:
                return "yellow record";
            case 2257:
                return "green record";
            default:
                return "notfound";
        }
    }

}
